<template lang="html">
  <div class="yo-scroll"
  :class="{'down':(state===0),'up':(state==1),'refresh':(state===2),'touch':touching}"
  @touchstart="touchStart($event)"
  @touchmove="touchMove($event)"
  @touchend="touchEnd($event)"
  @scroll="(onInfinite || infiniteLoading) ? onScroll($event) : undefined">
    <section class="inner" ref="inner" :style="{ transform: 'translate3d(0, ' + top + 'px, 0)' }">
      <header class="pull-refresh">
        <slot name="pull-refresh">
           <span class="down-tip">下拉更新</span>
           <span class="up-tip">松开更新</span>
           <span class="refresh-tip">更新中</span>
        </slot>
      </header>
      <slot></slot>
      <footer class="load-more">
        <slot name="load-more">
          <span>{{enableInfinite?'---已经到底了---':"正在加载....."}}</span>
        </slot>
      </footer>
    </section>
  </div>
</template>
 
<script>
export default {
  props: {
    offset: {
      type: Number,
      default: 40,
    },
    enableInfinite: {
      type: Boolean,
      default: true,
    },
    enableRefresh: {
      type: Boolean,
      default: true,
    },
    onRefresh: {
      type: Function,
      default: undefined,
      required: false,
    },
    onInfinite: {
      type: Function,
      default: undefined,
      require: false,
    },
  },
  data() {
    return {
      top: 0,
      state: 0,
      startY: 0,
      touching: false,
      infiniteLoading: false,
    };
  },
  methods: {
    touchStart(e) {
      console.log("获取的e", e);
      this.startY = e.targetTouches[0].pageY;
      console.log("获取的startY", this.startY);
      //获取的滑动的距离
      this.startScroll = this.$el.scrollTop || 0;
      console.log("获取的startScroll", this.startScroll);
      this.touching = true;
    },
    touchMove(e) {
      if (!this.enableRefresh || this.$el.scrollTop > 0 || !this.touching) {
        return;
      }
      console.log(
        "获取的e.targetTouches[0].pageY",
        e.targetTouches[0].pageY,
        this.startY,
        this.startScroll
      );
      let diff = e.targetTouches[0].pageY - this.startY - this.startScroll;
      console.log("获取的diff", diff);
      if (diff > 0) e.preventDefault();
      console.log("this.offset", this.offset, "diff", diff);
      this.top = Math.pow(diff, 0.8) + (this.state === 2 ? this.offset : 0);
      console.log("获取的top", this.top);
      if (this.state === 2) {
        // in refreshing
        return;
      }
      if (this.top >= this.offset) {
        this.state = 1;
      } else {
        this.state = 0;
      }
    },
    touchEnd(e) {
      if (!this.enableRefresh) return;
      this.touching = false;
      if (this.state === 2) {
        // in refreshing
        this.state = 2;
        this.top = this.offset;
        return;
      }
      if (this.top >= this.offset) {
        // do refresh
        this.refresh();
      } else {
        // cancel refresh
        this.state = 0;
        this.top = 0;
      }
    },
    refresh() {
      this.state = 2;
      this.top = this.offset;
      this.onRefresh(this.refreshDone);
    },
    refreshDone() {
      this.state = 0;
      this.top = 0;
    },

    infinite() {
      this.infiniteBegin();
      this.onInfinite(this.infiniteDone);
    },
    infiniteBegin() {
      this.infiniteLoading = true;
    },
    infiniteDone() {
      this.infiniteLoading = false;
    },

    onScroll(e) {
      console.log(
        "this.enableInfinite||this.infiniteLoading",
        this.enableInfinite,
        this.infiniteLoading
      );
      if (this.enableInfinite || this.infiniteLoading) {
        return;
      }
      console.dir(this.$el);
      //当前屏幕的高度
      let outerHeight = this.$el.clientHeight;
      console.log("outerHeight", outerHeight);
      //获取的列表的高度
      let innerHeight = this.$refs.inner.clientHeight;
      console.log("获取的innerHeight", innerHeight);
      //网页卷进去的高度
      let scrollTop = this.$el.scrollTop;
      console.log("scrollTop", scrollTop);
      //头部刷新的高度
      let ptrHeight = this.onRefresh
        ? this.$el.querySelector(".pull-refresh").clientHeight
        : 0;
      console.log("ptrHeight", ptrHeight);
      ///底部的加载中的高度
      let infiniteHeight = this.$el.querySelector(".load-more").clientHeight;
      // 获取的底部信息
      let bottom = innerHeight - outerHeight - scrollTop - ptrHeight;
      console.log("bottom", bottom);
      if (bottom < infiniteHeight) this.infinite();
    },
    throttleScroll(e){
      throttle(onScroll(e),200)
    },
    //
    throttle(fn,delay){
      let now,lastExec,timer,context,args;
      let execute=function (params) {
        fn.apply(context,args)

      }
      return function (){
        context=this;
        args=arguments;
        now =Date.now()
        if(timer){
          clearTimeout(timer);
          timer=null
        }
        if(lastExec){
          let diff=delay-(now-lastExec)
          if(diff<0){
            execute()
          }else{
            timer=setTimeout(() => {
              execute()
            }, diff);
          }
        }else{
          execute()
        }
      }
    }
  },
};
</script>
<style>
.yo-scroll {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  overflow: auto;
  -webkit-overflow-scrolling: touch;
  background-color: #ddd;
}
.yo-scroll .inner {
  position: absolute;
  top: -2rem;
  width: 100%;
  transition-duration: 300ms;
}
.yo-scroll .pull-refresh {
  position: relative;
  left: 0;
  top: 0;
  width: 100%;
  height: 2rem;
  display: flex;
  align-items: center;
  justify-content: center;
}
.yo-scroll.touch .inner {
  transition-duration: 0ms;
}
.yo-scroll.down .down-tip {
  display: block;
}
.yo-scroll.up .up-tip {
  display: block;
}
.yo-scroll.refresh .refresh-tip {
  display: block;
}
.yo-scroll .down-tip,
.yo-scroll .refresh-tip,
.yo-scroll .up-tip {
  display: none;
}
.yo-scroll .load-more {
  height: 3rem;
  display: flex;
  align-items: center;
  justify-content: center;
}
</style>